wayland: don't handle buffer release centrally
authorRay Strode <rstrode@redhat.com>
Tue, 2 Feb 2016 19:36:25 +0000 (14:36 -0500)
committerRay Strode <rstrode@redhat.com>
Sat, 6 Feb 2016 13:02:57 +0000 (08:02 -0500)
Right now we handle buffer releases coming from the
compositor in a central place. We add a listener when
first creating the shared buffers.

This is problematic because a buffer can only have
one listener on it at once so users of the buffer
can't get notified when it's released.

This commit moves the buffer listener code from the
centrally managed display code to the cursor and window
code.

https://bugzilla.gnome.org/show_bug.cgi?id=761312

gdk/wayland/gdkcursor-wayland.c
gdk/wayland/gdkdisplay-wayland.c
gdk/wayland/gdkwindow-wayland.c

index 4f938178befab88725a9a5ba8ed9463324559e96..4119633c79ee5b9768d17280e8f80041671cdb69 100644 (file)
@@ -401,6 +401,19 @@ _gdk_wayland_display_get_cursor_for_type (GdkDisplay    *display,
                                                               1);
 }
 
+static void
+buffer_release_callback (void             *_data,
+                         struct wl_buffer *wl_buffer)
+{
+  cairo_surface_t *cairo_surface = _data;
+
+  cairo_surface_destroy (cairo_surface);
+}
+
+static const struct wl_buffer_listener buffer_listener = {
+  buffer_release_callback
+};
+
 GdkCursor *
 _gdk_wayland_display_get_cursor_for_surface (GdkDisplay *display,
                                             cairo_surface_t *surface,
@@ -409,6 +422,7 @@ _gdk_wayland_display_get_cursor_for_surface (GdkDisplay *display,
 {
   GdkWaylandCursor *cursor;
   GdkWaylandDisplay *wayland_display = GDK_WAYLAND_DISPLAY (display);
+  struct wl_buffer *buffer;
   cairo_t *cr;
 
   cursor = g_object_new (GDK_TYPE_WAYLAND_CURSOR,
@@ -439,6 +453,10 @@ _gdk_wayland_display_get_cursor_for_surface (GdkDisplay *display,
                                                                            cursor->surface.width,
                                                                            cursor->surface.height,
                                                                            cursor->surface.scale);
+
+  buffer = _gdk_wayland_shm_surface_get_wl_buffer (cursor->surface.cairo_surface);
+  wl_buffer_add_listener (buffer, &buffer_listener, cursor->surface.cairo_surface);
+
   if (surface)
     {
       cr = cairo_create (cursor->surface.cairo_surface);
index 500e211c5d0fede4c93fcbacd5532eb42abc0c20..db02c73d8433ee834e26b1a1dc87f1e1ba95506a 100644 (file)
@@ -908,19 +908,6 @@ typedef struct _GdkWaylandCairoSurfaceData {
   uint32_t scale;
 } GdkWaylandCairoSurfaceData;
 
-static void
-buffer_release_callback (void             *_data,
-                         struct wl_buffer *wl_buffer)
-{
-  cairo_surface_t *surface = _data;
-
-  cairo_surface_destroy (surface);
-}
-
-static const struct wl_buffer_listener buffer_listener = {
-  buffer_release_callback
-};
-
 static struct wl_shm_pool *
 create_shm_pool (struct wl_shm  *shm,
                  int             size,
@@ -1015,7 +1002,6 @@ _gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *display,
   data->buffer = wl_shm_pool_create_buffer (data->pool, 0,
                                             width*scale, height*scale,
                                             stride, WL_SHM_FORMAT_ARGB8888);
-  wl_buffer_add_listener (data->buffer, &buffer_listener, surface);
 
   cairo_surface_set_user_data (surface, &gdk_wayland_shm_surface_cairo_key,
                                data, gdk_wayland_cairo_surface_destroy);
index 1c509e59cb83f09e91f3925d055e09bbf18ce40e..d0707c1cb25e3c2a6c9073f858d263a024fac6f9 100644 (file)
@@ -580,6 +580,19 @@ gdk_wayland_window_attach_image (GdkWindow *window)
   impl->pending_commit = TRUE;
 }
 
+static void
+buffer_release_callback (void             *_data,
+                         struct wl_buffer *wl_buffer)
+{
+  cairo_surface_t *cairo_surface = _data;
+
+  cairo_surface_destroy (cairo_surface);
+}
+
+static const struct wl_buffer_listener buffer_listener = {
+  buffer_release_callback
+};
+
 static void
 gdk_wayland_window_ensure_cairo_surface (GdkWindow *window)
 {
@@ -601,11 +614,14 @@ gdk_wayland_window_ensure_cairo_surface (GdkWindow *window)
   else if (!impl->cairo_surface)
     {
       GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (impl->wrapper));
+      struct wl_buffer *buffer;
 
       impl->cairo_surface = _gdk_wayland_display_create_shm_surface (display_wayland,
                                                                      impl->wrapper->width,
                                                                      impl->wrapper->height,
                                                                      impl->scale);
+      buffer = _gdk_wayland_shm_surface_get_wl_buffer (impl->cairo_surface);
+      wl_buffer_add_listener (buffer, &buffer_listener, impl->cairo_surface);
     }
 }